package com.game.tiledmap;

import java.util.LinkedList;

import android.graphics.Point;
import android.graphics.Rect;

import com.game.character.Player;
import com.game.framwork.gamesupport.Camera;
import com.game.framwork.itf.Graphics;
import com.game.object.JObject;
import com.game_ltdd.Resrouce;

public class TiledMap {
	public static int GRASS = 0;
	public static int ROAD = 1;
	public static int LINE = 2;
	public static int CROSS = 3;
	public static int TREE = 4;
	public static int HOUSE_YELLOW = 5;
	public static int HOUSE_RED = 6;
	public static int HOUSE_BLUE = 7;

	public int numPaint;
	public int[][] map;
	public int mapWidth;
	public int mapHeight;
	public int cellSize;

	public Point mapPos;
	private Camera camera;
	public LinkedList<Tiled> tiledLayer;

	public Point playerPos;
	public Player player;

	public TiledMap() {
		camera = new Camera(0, 0);
		tiledLayer = new LinkedList<Tiled>();
		mapPos = new Point(0, 0);
		map = null;
		player = null;
		mapWidth = 0;
		mapHeight = 0;
		cellSize = 0;
	}

	public void attachCamera(Camera camera) {
		this.camera = camera;
	}

	private void resetMap() {
		for (int i = 0; i < mapHeight; i++) {
			for (int j = 0; j < mapWidth; j++) {
				map[i][j] = 0;
			}
		}
	}

	public void initMap(int numCol, int numRow, int cellSize) {
		mapWidth = numCol;
		mapHeight = numRow;
		map = new int[mapHeight][mapWidth];
		this.cellSize = cellSize;
		resetMap();
	}

	public void setMapPos(Point startPos) {
		mapPos = new Point(startPos.x + cellSize / 2, startPos.y + cellSize / 2);
	}

	public void setCell(int row, int col, int type) {
		if (col >= mapWidth) {
			return;
		}
		if (row >= mapHeight) {
			return;
		}
		map[row][col] = type;
		Tiled tiled = new Tiled(row * mapWidth + col, type, Resrouce.mapObject);
		tiled.setPossition(new Point(mapPos.x + col * cellSize, mapPos.y + row
				* cellSize));
		tiled.attachTiledMap(this);
		tiledLayer.add(row * mapWidth + col, tiled);
	}

	public int getCell(int row, int col) {
		if (row >= mapHeight) {
			return -1;
		}
		if (col >= mapWidth) {
			return -1;
		}
		return map[row][col];
	}

	public void render(Graphics g, float deltaTime) {
		numPaint = 0;
		// render tiled
		int startCheckX = 0;
		int startCheckY = 0;
		int endCheckX = mapHeight;
		int endCheckY = mapWidth;
		for (int i = startCheckX; i < endCheckX; i++) {
			for (int j = startCheckY; j < endCheckY; j++) {
				tiledLayer.get(i * mapWidth + j).updateAnimation(deltaTime);

				if (j * cellSize + camera.getCameraX() + cellSize >= 0
						&& j * cellSize + camera.getCameraX() - 2 * cellSize < 800
						&& i * cellSize + camera.getCameraY() + cellSize + 32 >= 0
						&& i * cellSize + camera.getCameraY() - 2 * cellSize < 480) {
					tiledLayer.get(i * mapWidth + j).paintInternal(g);
					numPaint++;
				}
			}
		}
	}

	public Camera getCamera() {
		return camera;
	}

	public Point convertToMapIndex(Point pos) {

		int row = pos.y / cellSize;
		int col = pos.x / cellSize;
		Point newPos = new Point();
		newPos = new Point(row, col);

		return newPos;
	}

	public Point convertToMapPos(Point pos) {
		Point newPos = new Point();
		Point mapPos = new Point();

		mapPos = convertToMapIndex(pos);

		if (mapPos.y < 0)
			mapPos.y = 0;
		if (mapPos.y > mapHeight)
			mapPos.y = mapHeight - 1;
		if (mapPos.x < 0)
			mapPos.x = 0;
		if (mapPos.x > mapWidth)
			mapPos.x = mapWidth - 1;

		newPos.x = mapPos.x + mapPos.y * cellSize;
		newPos.y = mapPos.y + mapPos.x * cellSize;

		if (pos.x - newPos.x >= 40)
			newPos.x += cellSize;
		if (pos.y - newPos.y >= 45)
			newPos.y += cellSize;

		return newPos;
	}

	public LinkedList<Tiled> getListObjectMapToCheckCollision(Rect rect) {
		LinkedList<Tiled> listCollision = new LinkedList<Tiled>();
		int left = (rect.left - camera.getCameraX()) / cellSize;
		int right = (rect.right - camera.getCameraX()) / cellSize;
		int top = (rect.top - camera.getCameraY()) / cellSize;
		int bottom = (rect.bottom - camera.getCameraY()) / cellSize;

		for (int i = top; i <= bottom; i++) {
			for (int j = left; j <= right; j++) {
				if (i >= mapHeight || j >= mapWidth || i < 0 || j < 0) {
					continue;
				}
				if (map[i][j] != 0) {
					listCollision.add(tiledLayer.get(i * mapWidth + j));
				}
			}
		}
		return listCollision;
	}

	public static void updatePlayerPosToMap(JObject player, TiledMap map) {
		if (player.getPossition().x - player.getBoundBox().width() / 2 < 0) {
			player.setPossition(new Point(player.getBoundBox().width() / 2,
					player.getPossition().y));
		}
		if (player.getPossition().y - player.getBoundBox().height() / 2 < 0) {
			player.setPossition(new Point(player.position.x, player
					.getBoundBox().height() / 2));
		}
		if (player.getPossition().x + player.getBoundBox().width() / 2 > map.mapWidth
				* map.cellSize) {
			player.setPossition(new Point(map.mapWidth * map.cellSize
					- player.getBoundBox().width() / 2, player.getPossition().y));
		}
		if (player.getPossition().y + player.getBoundBox().height() / 2 > map.mapHeight
				* map.cellSize) {
			player.setPossition(new Point(player.getPossition().x,
					map.mapHeight * map.cellSize
							- player.getBoundBox().height() / 2));
		}
		Point pos = map.convertToMapIndex(new Point(player.getPossition().x,
				player.getPossition().y));
		map.playerPos = pos;
	}
}
